HTTP 與 Cookie 都是明碼傳輸,這對做身分驗證並不是件有利的事。這就像是結帳刷卡的時候,大喊自己的帳號密碼一樣,路人聽到就能盜刷了。
最理想的情況當然是「天知地知,你知我知」。在網路世界裡,因為大家都在同一個載體上傳輸資料,因此任何資料都有被截取的機會,因此只能退而求其次:「我講只有你聽得懂的話,你講只有我聽得懂的話」。現實社會中,比較難做到這種程度,但電腦的世界裡,這正是密碼學主要在討論的。
今天會先討論密碼學實際的應用--SSL/TLS,後面再討論細節。
為何筆者這麼愛討論歷史呢?因為在挖歷史的過程總是能解決很多奇妙的問題。比方說 SSL 和 TLS 到底有何不同,挖完才發現它們之間的關係。
SSL 全名為 Secure Sockets Layer,TLS 全名為 Transport Layer Security。以下參考維基百科的資料。
SSL 1.0
是由 Netscape 設計的,但時間不詳。SSL 2.0
1995 年發布,2011 年棄用。SSL 3.0
1996 年發布,2015 年棄用。後來 IETF 也將此協定特別發布了 RFC 6101 作為歷史記錄。TLS 1.0
1999 年 IETF 將 SSL 標準化,發布了 RFC 2246,同時改名為 TLS。也因此 SSL 3.0 和 TLS 1.0 其實沒有什麼太大差別,甚至可以說是一樣的東西。而 TLS 1.0 也支援相容 SSL 3.0 的功能,但這做法同時也降低了安全性。TLS 1.1
2006 年發布 RFC 4346,雖然目前沒什麼問題,還是計劃於 2020 年棄用TLS 1.2
2008 年發布 RFC 5246,可運作在 HTTP/2 上。TLS 1.3
2018 年發布 RFC 8446
注意看了一下,TLS 每個 RFC 都是
46
結尾,不知道是不是故意的。
值得一提的是,HTTP/2 協定是允許非加密的,同時也允許 TLS 1.2 或更新的版本,但目前主流瀏覽器都只實作加密的 HTTP/2,這讓 HTTP/2 + TLS 變成了強制標準。
TLS 在 OSI 模型裡,它屬於傳輸層的協定,而簡介 HTTP 是有提到 HTTP 是應用層協定。而 OSI 模型在設計上是符合里氏替換原則與依賴反轉原則的,這代表傳輸層是否有 TLS 是不會影響應用層的 HTTP;反之,不管應用層是 HTTP、FTP 或 SMTP 等,都能使用 TLS 加密。
傳輸層上還有另一個廣泛使用的協定--RFC 793 - Transmission Control Protocol(TCP),裡面有提到一開始建立連線的方法,即為 Three-way Handshake。
時序圖如下:
@startuml
Alice -> Bob: SYN
Alice <- Bob: SYN-ACK
Alice -> Bob: ACK
@enduml
簡單來說,這過程有點像在打電話:
然後就可以開始正常講話了。
在 TCP Three-way Handshake 完成之後,如果 Alice 有希望使用 SSL 加密時就會開始做 SSL Handshake。時序圖如下:
@startuml
Alice -> Bob: (1) hello
note left
Highest SSL version
Cipher supported
Data Compression Method
etc.
end note
Alice <- Bob: (2) hello
note right
Selected SSL version
Selected Cipher
Selected Data Compression Method
Certificate
etc.
end note
Alice -> Alice: (3) Validate Certificate
Alice -> Bob: (4) Certificate
Bob -> Bob: (5) Validate Certificate
Alice -> Bob: (6) Key exchange
Alice -> Bob: (7) Change Cipher Spec
Alice -> Bob: (8) Finished
Alice <- Bob: (9) Change Cipher Spec
Alice <- Bob: (10) Finished
Alice <-> Bob: (11) Encrypted Data Transfer
@enduml
以上是簡單版的 HTTP + TLS 傳輸流程,有省略非常多細節沒說明,如加密演算法或 Certificate 如何驗證等,未來會再補充說明這些細節,有興趣的讀者可以參考下面的補充資料了解。